package com.united.ucts.modules.auth.controller;

import com.united.frame.common.constant.AuthConstant;
import com.united.frame.common.exception.AuthException;
import com.united.frame.common.module.result.Result;
import com.united.frame.plugin.security.Oauth2Token;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义Oauth2获取令牌接口
 *
 * @author hudan
 * @version 1.0
 * @filename AuthController.java
 * @copyright <a href="www.united.cn">www.united.cn</a>
 * @date 2019-10-10
 */
@Slf4j
@RequiredArgsConstructor
@Api(value = "AuthController", tags = "认证中心登录认证")
@RestController
@RequestMapping("/oauth")
public class AuthController {

    private final TokenEndpoint tokenEndpoint;

    @ApiOperation("Oauth2获取token")
    @PostMapping(value = "/token")
    public Result<Oauth2Token> postAccessToken(HttpServletRequest request,
                                                        @ApiParam("授权模式") @RequestParam String grant_type,
                                                        @ApiParam("Oauth2客户端ID") @RequestParam String client_id,
                                                        @ApiParam("Oauth2客户端秘钥") @RequestParam String client_secret,
                                                        @ApiParam("刷新token") @RequestParam(required = false) String refresh_token,
                                                        @ApiParam("登录用户名") @RequestParam(required = false) String username,
                                                        @ApiParam("登录密码") @RequestParam(required = false) String password)  {
        try {
            Map<String, String> parameters = new HashMap<>(6);
            parameters.put("grant_type", grant_type);
            parameters.put("client_id", client_id);
            parameters.put("client_secret", client_secret);
            parameters.putIfAbsent("refresh_token", refresh_token);
            parameters.putIfAbsent("username", username);
            parameters.putIfAbsent("password", password);

            // 通过spring-security调用相应用户微服务的loadUserByUsername,获取用户信息
            OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(request.getUserPrincipal(), parameters).getBody();

            assert oAuth2AccessToken != null;
            return Result.success(Oauth2Token.builder()
                    .token(oAuth2AccessToken.getValue())
                    .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
                    .expiresIn(oAuth2AccessToken.getExpiresIn())
                    .tokenHead(AuthConstant.JWT_TOKEN_PREFIX).build());
        } catch (Exception e) {
            log.error("通过Oauth2获取token信息失败:", e);
            throw new AuthException(e.getMessage());
        }
    }
}